<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
		"http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<title>robot Tree selector Test</title>

		<style>
			@import "../../../../util/doh/robot/robot.css";
		</style>

		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>

		<script type="text/javascript">
			require([
				"doh/runner", "dojo/robotx",
				"dojo/_base/array", "dojo/dom", "dojo/dom-geometry", "dojo/keys", "dojo/sniff", "dojo/window",
				"dijit/tests/tree/robot/Tree_dnd", "dojo/domReady!"
			], function(doh, robot, array, dom, domGeom, keys, has, winUtils, dndHelpers){

				function clickItem(modifiers){
					var i;
					for(i = 0; i < modifiers.length; i++){
						robot.keyDown(modifiers[i], 250);
					}
					robot.mouseClick({left: true}, 250);
					for(i = modifiers.length - 1; i >= 0; i--){
						robot.keyUp(modifiers[i], 250);
					}
				}

				function pressEnter(modifiers){
					var i;
					for(i = 0; i < modifiers.length; i++){
						robot.keyDown(modifiers[i], 250);
					}

					// Use ENTER on mac because meta-space controls the IME (switching input language),
					// but SPACE on IE6 because ctrl-shift-ENTER doesn't do anything (although not sure
					// why we are testing ctrl-shift combination anyway)
					robot.keyPress(has("mac") ? keys.ENTER : keys.SPACE, 250);

					for(i = modifiers.length - 1; i >= 0; i--){
						robot.keyUp(modifiers[i], 250);
					}
				}
				function mouseSelectExpendo(tree, item, modifiers, k){
					robot.mouseMoveAt(item.expandoNode, 250);
					clickItem(modifiers);
					robot.sequence(k);
				}
				function mouseSelect(tree, item, modifiers, k){
					robot.mouseMoveAt(item.domNode, 250, 200);
					clickItem(modifiers);
					robot.sequence(k);
				}
				function keyboardSelect(tree, item, modifiers, k){
					var curFocus = robot.window.require("dijit/focus").curNode,
						focused = dom.isDescendant(curFocus, dom.byId("itemTree", robot.doc));
					if(!focused){
						robot.keyPress(keys.TAB, 250);
						robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 250);
						return;
					}

					focused_node = curFocus.parentNode.parentNode.parentNode;
					var diff = domGeom.position(item.domNode).y - domGeom.position(focused_node).y;
					if(diff != 0){
						if(diff > 0){
							robot.keyPress(keys.DOWN_ARROW, 500);
						}else{
							robot.keyPress(keys.UP_ARROW, 500);
						}
					}else{
						pressEnter(modifiers);
						robot.sequence(k);
						return;
					}
					robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 500);
				}

				function getSelected(tree){
					//in IE, for(var i in object) will not honor the order the properties are set
					//(it's in the order properties are first set even delete a property won't
					//change it)
					var selected = tree.dndController.getSelectedTreeNodes();
					selected.sort(function(a, b){return a.item.id<b.item.id?-1:1});
					return selected;
				}
				function testSingleItem(selector, clicker, itemName){
					var d = new doh.Deferred();

					// Find the fruitsTreeNode category
					var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", itemName || "Fruits");
					var tree = registry.byId("itemTree");

					// select fruit item
					selector(tree, fruitsTreeNode, [], function(){
						robot.sequence(d.getTestErrback(function(){
							var selected = getSelected(tree);

							doh.is(1, selected.length);
							doh.is(fruitsTreeNode, selected[0]);

							//ctrl-click the item to deselect it
							clicker([has("mac") ? keys.META : keys.CTRL]);

							robot.sequence(d.getTestCallback(function(){
								var selected = getSelected(tree);

								doh.is(0, selected.length);
							}), 500);
						}), 500);
					});
					return d;
				}
				function testCtrlSelect(selector, clicker){
					var d = new doh.Deferred();

					// Find the fruitsTreeNode category
					var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits");
					var tree = registry.byId("itemTree");

					// select fruit item
					selector(tree, fruitsTreeNode, [], function(){
						robot.sequence(function(){
							winUtils.scrollIntoView(dom.byId("itemTree", robot.doc));
						}, 500);

						// ctrl-click Cereals item
						var cerealsTreeNode = dndHelpers.findTreeNode("itemTree", "Cereals");
						selector(tree, cerealsTreeNode,
								 [has("mac") ? keys.META : keys.CTRL], function(){
							 robot.sequence(d.getTestCallback(function(){
								 var selected = getSelected(tree);

								 doh.is(2, selected.length);
								 doh.is(fruitsTreeNode, selected[0]);
								 doh.is(cerealsTreeNode, selected[1]);
								 doh.is(cerealsTreeNode, tree.dndController.anchor, 'anchor should be the Cereals item');
							 }), 500); });
					});
					return d;
				}
				function _getCtrlShiftTest(selector, keys){
					return function(){
						var d = new doh.Deferred();

						// Find the fruitsTreeNode category
						var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits");
						var cerealsTreeNode = dndHelpers.findTreeNode("itemTree", "Cereals");
						var vegetablesTreeNode = dndHelpers.findTreeNode("itemTree", "Vegetables");
						var tree = registry.byId("itemTree");

						// select fruit item (no modifiers)
						selector(tree, fruitsTreeNode, [], atFruits);

						function atFruits(){
							// shift-select Cereals item
							selector(tree, cerealsTreeNode, keys, atCereals);
						}
						function atCereals(){
							robot.sequence(d.getTestErrback(function(){
								var selected = getSelected(tree);

								doh.is(3, selected.length);
								doh.is(fruitsTreeNode, selected[0]);
								doh.is(vegetablesTreeNode, selected[1]);
								doh.is(cerealsTreeNode, selected[2]);
								doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 1');

								// shift-select Vegetables item
								keyboardSelect(tree, vegetablesTreeNode, keys, atVegetables);
							}));
						}

						function atVegetables(){
							robot.sequence(d.getTestCallback(function(){
								var selected = getSelected(tree);
								doh.is(2, selected.length);
								doh.is(fruitsTreeNode, selected[0]);
								doh.is(vegetablesTreeNode, selected[1]);
								doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 2');
							}));
						}

						return d;
					};
				}

				var controller = '', ind=window.location.href.indexOf("?controller=");
				
				if(ind > -1){
					controller = window.location.href.substr(ind + 12);
					controller = controller.split('&')[0];
				}
				robot.initRobot('../test_Tree_DnD.html?testController=' + controller);

				dndHelpers.setup();

				doh.register("focus page", {
					name: "focus page",
					timeout: 20000,
					runTest: function(){
						var d = new doh.Deferred();
						robot.mouseMove(10, 10, 100, 100);
						robot.mouseClick({left:true}, 100);
						robot.sequence(function(){
                            //Focus the page, so tabbing will work.
							d.callback(true);
						}, 250);
						return d;
					}
				});
				doh.register("item selection (keyboard)", itemSelection(keyboardSelect, pressEnter) );
				doh.register("item selection (mouse)", itemSelection(mouseSelect, clickItem) );
				doh.register({name:"item selection (mouse on expando)", timeout: 15000, runTest: function(){
					return testSingleItem(mouseSelectExpendo, clickItem, 'Cereals');
				}});

				// Failsafe to clear pressed keys in case above tests timeout etc.
				doh.register("clear pressed keys", function(){
					var d = new doh.Deferred();
					array.forEach([keys.META, keys.CTRL, keys.SHIFT], function(key){
						robot.keyUp(key, 250);
					});
					robot.sequence(function(){
						d.callback(true);
					});
					return d;
				});

				function itemSelection(selector, clicker){
					return [
						{
							name: "select/deselect a single item",
							timeout: 15000,
							runTest: function(){ return testSingleItem(selector, clicker); }
						},
						{
							name: "ctrl select",
							timeout: 15000,
							runTest: function(){ return testCtrlSelect(selector, clicker); }
						},
						{
							name: "shift select",
							timeout: 15000,
							runTest: _getCtrlShiftTest(selector, [keys.SHIFT])
						},
						{
							name: "ctrl shift select",
							timeout: 15000,
							runTest: _getCtrlShiftTest(selector, [has("mac") ? keys.META : keys.CTRL, keys.SHIFT])
						}
					];
				}
				
				doh.run();
			});
		</script>
	</head>
</html>
